/**
 ** Copyright (c) 2010, GE Healthcare
 ** All rights reserved.
 **
 ** Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
 ** following conditions are met:
 ** 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
 **    following disclaimer.
 ** 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
 **    disclaimer in the documentation and/or other materials provided with the distribution.
 ** 3. Neither the name of the GE Healthcare nor the names of its contributors may be used to endorse or promote products
 **    derived from this software without specific prior written permission.
 **
 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 ** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 ** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * This software was created by its contributors for NHINDirect.org for the sole purpose of demonstrating the
 * viability of using Integrating the Healthcare Enterprise (IHE) in accordance with the proposed
 * IHE NHIN Direct Specfication.
 *
 * References:
 * http://nhindirect.org/
 * http://nhindirect.org/NHIN+Direct+Abstract+Model
 * http://nhindirect.org/IHE+NHIN+Direct+Specification
 *
 * Contributors:
 * mailto:/matt.potter@ge.com
 */

package org.nhindirect;

import org.openhealthtools.ihe.atna.auditor.XDSSourceAuditor;
import org.openhealthtools.ihe.xds.response.XDSErrorListType;
import org.openhealthtools.ihe.xds.response.XDSErrorType;
import org.openhealthtools.ihe.xds.response.XDSResponseType;
import org.openhealthtools.ihe.xds.response.XDSStatusType;
import org.openhealthtools.ihe.xds.source.B_Source;
import org.openhealthtools.ihe.xds.source.SubmitTransactionData;

import java.net.URI;

/**
 * Demonstrates transmitting a well formed XDS Repository Submission to a XDR Document Recipient
 * endpoint using OHT IHE Profiles libraries.
 *
 * Note that this is meant to be part of protocol adapters on a Source HISP that already plays the
 * role of an XDR Document Recipient.  Thus the transaction invoked here is not meant to be 'visible'
 * outside of the system realizing the NHIN Source HISP role.  In other words, this code doesn't
 * have to handle resolving NHIN Addressing since the Source HISP's XDR Document Recipient component
 * would deal with this.
 *
 * Source => ( Source HISP Adapter (this code) --> Source HISP XDR ) => Destination HISP => Destination
 */
public class XDRDocumentSource {

    private URI xdrEndpoint;
    private String xdsSourceId;
    private String xdsSourceAgentName;

    public XDRDocumentSource(String xdsSourceId, String xdsSourceAgentName, URI xdrEndpoint) {
        this.xdrEndpoint = xdrEndpoint;
        this.xdsSourceAgentName = xdsSourceAgentName;   // TODO wire up the ATNA
        this.xdsSourceId = xdsSourceId;
    }

    /**
     * Submits the specified XDS submission set, document(s) folders to this instance's XDR endpoint.  Applies
     * this instances default source OID to the XDSSubmissionSet.sourceId before transmission
     * if its not already in the txnData specified by the caller.
     */
    public void submit(SubmitTransactionData txnData) throws Exception {

        encodeSubmissionWithXDSSourceId(txnData, xdsSourceId);

        B_Source docSource = new B_Source(xdrEndpoint);
        XDSSourceAuditor.getAuditor().getConfig().setAuditorEnabled(false);
        XDSResponseType response = docSource.submit(txnData);
        XDSStatusType status = response.getStatus();
        XDSErrorListType errorList = response.getErrorList();
        if (errorList != null) {
            for (Object obj : errorList.getError()) {
                XDSErrorType error = (XDSErrorType) obj;
                System.err.printf("%s %s\n", error.getErrorCode().getLiteral(), error.getCodeContext());
            }
        }
        if (status.getLiteral().equals("Failure")) {
            throw new Exception("XDS P&R returned failure");
        }

    }

    private void encodeSubmissionWithXDSSourceId(SubmitTransactionData txnData, String xdsSourceId) {
        if (txnData.getSubmissionSet().getSourceId() == null) {
            txnData.getSubmissionSet().setSourceId(xdsSourceId);
        }
    }

}
